The specific example I have will increment obj[s] if it's truthy (has a value), and if it's falsey (doesn't exist in the object yet) it will set it equal to 1 and thus add it to the object.
But what I'm asking about, in general, looks like:
something = doIfTruthy || doIfFalsey
I'm thinking it must have a name, just like how we call this "ternary or conditional operator"
something = condition? ifTrue: ifFalse
I'd like to be able to refer to it by a proper name in my notes. Right now I'm just calling it "exploit truthy/falsey" because that's how I use it.
I'm also wondering what you call this kind of expression, because it's similar:
something = condition && ifTrue
You may refer to this page on MDN for more info on operators, but the gist of what you're asking is:
A || Bis called the "Logical OR" operator, where it will execute expressions left to right until it finds a truthy one, returning the 1st truthy expression.
A && Bis called the "Logical AND" operator, where it will execute expressions left to right until it finds a falsy one, returning the last truthy expression.
Side note:
I personally wouldn't recommend following in the code author's footsteps writing things like
obj[s] = ++obj[s] || 1, as even though it's concise, it takes some reading to understand. Consider something like:obj[s] ||= 0; ++obj[s];Or:
obj[s] = (obj[s] || 0) + 1;Or simply:
if (typeof obj[s] !== 'number') obj[s] = 0; ++obj[s];
For || operations, JS will return the FIRST "truthy" value it finds (reading left-to-right):
var bob = false || undefined || 0 || null || "hi"
// ^ ^ ^ ^ ^
// nope nope nope nope yip
//
// => bob = "hi"
// --------------
// breaking
// --------------
var bob = false || "hi" || 0 || null || undefined
// ^ ^
// nope yip <-- stops here
// the rest are ignored
//
// => bob = "hi"
Another trick is to use the && (and) to ensure something exists before accessing it.
For && operations, JS will return the LAST "truthy" value it finds (reading left-to-right).
For example if you're trying to read a property from a multi-level object.
var obj = {
foo : {
bar : "hi"
}
}
var bob = obj && obj.foo && obj.foo.bar;
// ^ ^ ^
// yip yip use this
//
// => bob = "hi"
// --------------
// breaking:
// --------------
var bob = obj && obj.foo && obj.foo.sally && obj.foo.bar;
// ^ ^ ^
// yip yip nope <-- stops here,
// ^ and returns the last "yip"
// | the rest are ignored |
// '-----------------------------------------------'
//
// => bob = obj.foo
Both || and && operations are read left-to-right... so you can have things that might normally throw errors toward the right side, since JS will simply stop reading left-to-right once it detects a truthy/falsey value.